﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using WallpaperEngineLib;
using WpfApp4.Models.Config;
using WpfApp4.Models;
using WpfApp4.Utilities;

using XEvent.Events;

using XEvent;

namespace WpfApp4.Views
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        private WindowEvent _windowEvent;

        public MainWindow()
        {
            InitializeComponent();

            Initialize();
            OnSubscribe();
        }

        #region WindowEvent

        private void OnSubscribe()
        {
            if (_windowEvent == null)
            {
                _windowEvent = XEventAgent.Instance.EventManager.GetEvent<WindowEvent>();
            }
            _windowEvent.Subscribe(OnOpenEditUrlWindow, (p) => p.Type == EventType.Action && p.WindowActionType == WindowActionType.Edit && p.EventId == EventId.OpenUrlWindow);
            _windowEvent.Subscribe(OnUpdateWebUrl, (p) => p.Type == EventType.Action && p.WindowActionType == WindowActionType.Update && p.EventId == EventId.UpdateUrl);
            _windowEvent.Subscribe(OnGetCurrentUrl, (p) => p.Type == EventType.Action && p.WindowActionType == WindowActionType.OK && p.EventId == EventId.GetCurrentUrl);
            _windowEvent.Subscribe(OnExitApp, (p) => p.Type == EventType.Action && p.WindowActionType == WindowActionType.Close && p.EventId == EventId.ExitApplication);
            _windowEvent.Subscribe(RefreshMenu, (p) => p.Type == EventType.Action && p.WindowActionType == WindowActionType.Update && p.EventId == EventId.RefreshMenu);
            _windowEvent.Subscribe(OnOpenWindow, (p) => p.Type == EventType.Action && p.WindowActionType == WindowActionType.Open && p.EventId == EventId.SettingWindow);
            _windowEvent.Subscribe(OnOpenBrowseWindow, (p) => p.Type == EventType.Action && p.WindowActionType == WindowActionType.Open && p.EventId == EventId.OpenBrowseWindow);
            _windowEvent.Subscribe(OnOpenInputBox, (p) => p.Type == EventType.Action && p.WindowActionType == WindowActionType.Open && p.EventId == EventId.OpenInputBox);
        }


        /// <summary>
        /// 打开地址栏
        /// </summary>
        /// <param name="args"></param>
        private void OnOpenEditUrlWindow(WindowEvent args)
        {
            Window urlInput = new UrlInputWindow();
            urlInput.Owner = this;
            var res = urlInput.ShowDialog();
            if (res.HasValue && res.Value)
            {
                if (args.CallBack is Action action)
                {
                    action.Invoke();
                }
            }
        }

        /// <summary>
        /// 更新地址
        /// </summary>
        /// <param name="args"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void OnUpdateWebUrl(WindowEvent args)
        {
            string url = args.Data as string;
            webView.Source = new Uri(url);
        }

        /// <summary>
        /// 获取当前Url
        /// </summary>
        /// <param name="args"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void OnGetCurrentUrl(WindowEvent args)
        {
            if (args.CallBack is Action<string> action)
            {
                action.Invoke(webView.Source.ToString());
            }
        }

        /// <summary>
        /// 退出程序
        /// </summary>
        /// <param name="obj"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void OnExitApp(WindowEvent obj)
        {
            this.Close();
            Application.Current.Shutdown();
        }

        /// <summary>
        /// 打开窗口
        /// </summary>
        /// <param name="event"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void OnOpenWindow(WindowEvent args)
        {
            var window = args.Data as Window;
            window.Owner = this;
            window.Show();
        }

        /// <summary>
        /// 打开浏览窗口
        /// </summary>
        /// <param name="event"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void OnOpenBrowseWindow(WindowEvent args)
        {
            var window = args.Data as Window;
            window.Show();
        }

        /// <summary>
        /// 打开输入框
        /// </summary>
        /// <param name="event"></param>
        /// <exception cref="NotImplementedException"></exception>
        private void OnOpenInputBox(WindowEvent args)
        {
            Window inputWindow = XEvent.Ioc.XContainerLocator.Instance.Resolve<InputWindow>("inputBox");
            inputWindow.Owner = this;
            var res = inputWindow.ShowDialog();
            if (res.HasValue && res.Value)
            {
                if(args.CallBack is Action action)
                {
                    action.Invoke();
                }
            }
        }

        #endregion

        #region Functions

        private void Initialize()
        {
            LoadMenu();
            webView.Source = new Uri(ApplicationConfigSetting.DefaultUrl);
        }

        /// <summary>
        /// 拖动窗口
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            try
            {
                DragMove();

                if (Right <= 0)
                {
                    this.Left = SystemParameters.PrimaryScreenWidth - 20;
                    _location = WindowLocationStyle.Hide;
                }
                else if (Left <= 0)
                {
                    this.Right = SystemParameters.PrimaryScreenWidth - 20;
                    _location = WindowLocationStyle.Hide;
                }
                else if (Top <= 0)
                {
                    this.Bottom = SystemParameters.PrimaryScreenHeight - 20;
                    _location = WindowLocationStyle.Hide;
                }
                else if (Bottom <= 0)
                {
                    this.Top = SystemParameters.PrimaryScreenHeight - 20;
                    _location = WindowLocationStyle.Hide;
                }
                else
                {
                    _location = WindowLocationStyle.Normal;
                }
            }
            catch { }
        }

        private WindowLocationStyle _location = WindowLocationStyle.Normal;
        private bool _isInWindow = false;
        private void DockPanel_MouseEnter(object sender, MouseEventArgs e)
        {
            try
            {
                if (_location == WindowLocationStyle.Hide)
                {
                    if (this.Left == SystemParameters.PrimaryScreenWidth - 20)
                    {
                        this.Right = 0;
                    }
                    else if (this.Right == SystemParameters.PrimaryScreenWidth - 20)
                    {
                        this.Left = 0;
                    }
                    else if (this.Bottom == SystemParameters.PrimaryScreenHeight - 20)
                    {
                        this.Top = 0;
                    }
                    else if (this.Top == SystemParameters.PrimaryScreenHeight - 20)
                    {
                        this.Bottom = 0;
                    }
                    _isInWindow = true;
                    _location = WindowLocationStyle.Over;
                }
            }
            catch { }
        }

        private void DockPanel_MouseLeave(object sender, MouseEventArgs e)
        {
            try
            {
                WallpaperEngine.Instance.DoGetCursorPos(out WallpaperEngineLib.Models.Point point);
                if (point.X >= Left + 20 && point.X <= (Left + body.Width + 20) && point.Y >= Top + 20 && point.Y <= (Top + body.Height + 20))
                {
                    _isInWindow = true;
                }
                else
                {
                    _isInWindow = false;
                }
                if (_location == WindowLocationStyle.Over && !_isInWindow)
                {
                    if (this.Right == 0)
                    {
                        this.Left = SystemParameters.PrimaryScreenWidth - 20;
                    }
                    else if (this.Left == 0)
                    {
                        this.Right = SystemParameters.PrimaryScreenWidth - 20;
                    }
                    else if (this.Top == 0)
                    {
                        this.Bottom = SystemParameters.PrimaryScreenHeight - 20;
                    }
                    else if (this.Bottom <= 0)
                    {
                        this.Top = SystemParameters.PrimaryScreenHeight - 20;
                    }
                    _location = WindowLocationStyle.Hide;
                }
            }
            catch { }
        }

        public double Right
        {
            get => SystemParameters.PrimaryScreenWidth - this.Left - body.Width - 40;
            set
            {
                this.Left = SystemParameters.PrimaryScreenWidth - value - body.Width - 40;
            }
        }

        public double Bottom
        {
            get => SystemParameters.PrimaryScreenHeight - this.Top - body.Height - 40;
            set
            {
                this.Top = SystemParameters.PrimaryScreenHeight - value - body.Height - 40;
            }
        }

        /// <summary>
        /// 加载菜单
        /// </summary>
        public void LoadMenu()
        {
            menus.Items.Clear();
            foreach (var item in MenuInfo.Instance.MenuItems)
            {
                var list = ConfigManager.CreateMenuItem(item);
                foreach (var menu in list)
                {
                    menus.Items.Add(menu);
                }
            }
        }

        private void RefreshMenu(WindowEvent @event)
        {
            var info = ConfigManager.LoadConfig();
            MenuInfo.Instance.MenuItems = info.MenuItems;
            MenuInfo.Instance.Settings = info.Settings;

            LoadMenu();
        }


        #endregion

        #region Override

        #endregion

        double l_bottom = 0;
        double l_right = 0;
        bool isKeyDown = false;
        Regex regex = new Regex(@"^[a-z,0-9]$", RegexOptions.IgnoreCase);

        private void Window_KeyDown(object sender, KeyEventArgs e)
        {
            if (_location != WindowLocationStyle.Hide)
            {
                return;
            }

            var key = e.Key.ToString();
            if (regex.IsMatch(key) || e.Key == Key.CapsLock)
            {
                if (!isKeyDown)
                {
                    l_bottom = Bottom;
                    l_right = Right;

                    Bottom = 0;
                    Right = SystemParameters.PrimaryScreenWidth / 2 - MenuInfo.Instance.Settings.PositionRight;
                    isKeyDown = true;
                }
            }
        }

        private void Window_KeyUp(object sender, KeyEventArgs e)
        {
            var key = e.Key.ToString();
            if (regex.IsMatch(key) || e.Key == Key.CapsLock)
            {
                Models.Time.Tick();
                if (isKeyDown && Models.Time.deltaTime > 0.2f)
                {
                    Bottom = l_bottom;
                    Right = l_right;

                    isKeyDown = false;
                }
            }
        }
    }

    public enum WindowLocationStyle
    {
        Normal,
        Hide,
        Over,
    }
}
